import os
import sqlite3
from pathlib import Path
import argparse
import shutil
import time

def check_and_connect_db(db_path):
    """检查并连接到SQLite数据库"""
    conn = sqlite3.connect(db_path)
    # 设置sqlite3.Row作为行工厂，以便能够使用字典访问字段
    conn.row_factory = sqlite3.Row
    cursor = conn.cursor()
    return conn, cursor

def fetch_zip_records(conn, cursor):
    """从zip_hash表中获取所有记录"""
    cursor.execute('SELECT * FROM zip_hash')
    records = cursor.fetchall()
    return records

def backup_file(file_path, backup_dir):
    """备份文件到指定目录，处理文件名冲突"""
    backup_dir_path = Path(backup_dir)
    backup_dir_path.mkdir(parents=True, exist_ok=True)

    timestamp = int(time.time())
    file_name = file_path.name
    backup_path = backup_dir_path / f"{file_name}.{timestamp}.bak"

    try:
        shutil.copy(str(file_path), str(backup_path))
        print(f"已备份文件: {file_path} 到 {backup_path}")
    except Exception as e:
        print(f"备份文件 {file_path} 时出错: {e}")

def replace_files(records, scan_dir, base_dir):
    """根据zip_hash表中的记录，检查并替换变更目录中的ZIP文件"""
    scan_dir_path = Path(scan_dir)
    backup_dir = scan_dir_path / 'backup'
    
    for record in records:
        file_path = record['file_path']
        file_name = record['file_name']
        source_path = Path(base_dir) / file_path / file_name
        target_path = scan_dir_path / file_path / file_name

        if target_path.exists():
            target_size = target_path.stat().st_size
            source_size = record['file_size']

            if target_size != source_size:
                backup_file(target_path, backup_dir)
                try:
                    shutil.copy2(str(source_path), str(target_path))
                    print(f"已替换文件: {source_path} 到 {target_path}")
                except FileNotFoundError:
                    print(f"警告: 源文件 {source_path} 不存在")
                except Exception as e:
                    print(f"处理文件 {source_path} 时出错: {e}")
            else:
                print(f"文件大小一致: {target_path}")
        else:
            print(f"文件不存在于目标目录: {target_path}")

def main(db_directory, scan_dir):
    db_path = str(Path(db_directory) / 'file_hashes.db')
    conn, cursor = check_and_connect_db(db_path)

    records = fetch_zip_records(conn, cursor)
    replace_files(records, scan_dir, db_directory)

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="根据zip_hash表中的记录，检查并替换变更目录中的ZIP文件")
    parser.add_argument('--db', required=True, help="SQLite数据库存放位置")
    parser.add_argument('--scan-dir', required=True, help="变更目录")

    args = parser.parse_args()

    db_directory = args.db
    scan_dir = args.scan_dir

    main(db_directory, scan_dir)